/**
 * @file Circle.as
 *  3D圆圈排列图片显示类
 * @author db0@qq.com
 * @version 1.0.1
 * @date 2017-10-28
 */
package futian
{
	import flash.display.DisplayObject;
	import flash.display.BitmapData;
	import flash.display.Bitmap;
	import flash.display.Sprite;
	import flash.geom.*;
	import flash.events.MouseEvent;
	import flash.events.Event;
	import flash.text.TextField;
	import flash.filters.BlurFilter;
	import flash.filters.GlowFilter;

	public class Circle extends Sprite
	{
		private var r:int;
		private var objArr:Array;
		public static const LEFT:String = "toleft";
		public static const RIGHT:String = "toright";
		public static const CLICK:String = "clicked";

		private var stageWidth:int;
		private var stageHeight:int;
		/**
		 * objArr 图片URL数组 {icon,name}
		 * _r	圈半径
		 * num	半圈显示的图片数量(图片总数2*num+1,第一张图居前面中间位置)
		 */
		public function Circle(objArr:Array, _r:int = 0, num:int = 8,stageWidth:int=1920,stageHeight:int=1080)
		{
			this.stageWidth = stageWidth;
			this.stageHeight= stageHeight;
			if (_r == 0)
				_r = stageWidth / 5;
			r = _r;

			x = stageWidth / 2;
			y = stageHeight *.58;
			z = 0;

			maxPhotos = num;
			this.objArr = objArr;

			//添加图片到容器
			if (objArr && objArr.length > 0)
			{
				addItem(0, true);
				var i:int = 0;
				while (i < num)
				{
					var h:int = i + 1;
					var addnew:Boolean = true;
					while (h >= objArr.length)
					{
						h -= objArr.length;
						addnew = false;
					}
					addItem(h, true,addnew);
					if(objArr.length>=3)
					{
						h = -i - 1;
						while (h < 0)
							h += objArr.length;
						addItem(h, false);
					}
					++i;
				}
			}

			index = 0;
			//事件
			addEventListener(RIGHT, prev);
			addEventListener(LEFT, next);
			addEventListener(CLICK, quit);
			addEventListener(Event.ADDED_TO_STAGE, init);
		}

		private var stageMouseX:int;
		private var stageMouseY:int;

		private function selected(e:Event):void
		{
			if(stage==null)
				return;
			if(stage.stageWidth*.4<=stage.mouseX && stage.mouseX <=stage.stageWidth*.6)
			{
				curPicture = e.target as PhotoLoader;
			}else{
				return;
			}
			if(curPicture==null || curPicture!=e.target)
			{
				stageMouseX = 0;
				stageMouseY = 0;
				return;
			}
			switch(e.type)
			{
				case MouseEvent.MOUSE_DOWN:
					stageMouseX = stage.mouseX;
					stageMouseY = stage.mouseY;
					break;
				case MouseEvent.MOUSE_UP:
					if(Math.abs(stageMouseX-stage.mouseX)<5 && Math.abs(stageMouseY-stage.mouseY)<5)
					{
						//logs.adds(curPicture.name,curPicture.obj.url);
						dispatchEvent(new Event(Event.COMPLETE));
					}else{
						stageMouseX = 0;
						stageMouseY = 0;
					}
					break;
			}
		}

		private function init(e:Event):void
		{//设置当前容器的3D视口
			removeEventListener(Event.ADDED_TO_STAGE, init);
			root.transform.perspectiveProjection.fieldOfView = 20;
			root.transform.perspectiveProjection.focalLength = r * 2;
			root.transform.perspectiveProjection.projectionCenter = new Point(stageWidth / 2, stageHeight * .5 + r * .08);
			parent.rotationX = 0;
		}

		private var index:int = 0;//当前图片在数组中的序号
		private const tweenTime:Number = 0.3;

		private function next(e:Event):void
		{//显示下一张图
			if (stage == null || !visible || objArr ==null || objArr.length==0)
				return;
			if(objArr.length==1)
				return;
			if(objArr.length == 2 && index==objArr.length-1)
				return;
			++index;
			if(index >= objArr.length)
				index -= objArr.length;

			removeEventListener(RIGHT, prev);
			removeEventListener(LEFT, next);

			var _rotationY:Number = rotationY;
			rotationY += eachAngle * 180 / Math.PI;

			TweenLite.killTweensOf(this, true);
			TweenLite.from(this, tweenTime, {rotationY: _rotationY, onComplete: onComplete});
			addEventListener(Event.ENTER_FRAME, onEnterFrame);

			var _index:int = index + maxPhotos;
			while(_index >= objArr.length)
				_index -= objArr.length;
			var addnew:Boolean = true;
			if(objArr.length==2){
				addnew = Boolean(_index>=objArr.length-1);
			}
			addItem(_index, true,addnew);
		}

		private function prev(e:Event):void
		{//显示上一张图
			if (stage == null || !visible || objArr ==null || objArr.length==0)
				return;
			if(objArr.length==1)
				return;
			if(objArr.length==2 && index==0)
				return;

			removeEventListener(RIGHT, prev);
			removeEventListener(LEFT, next);

			--index;
			if(index < 0)
				index += objArr.length;

			var _rotationY:Number = rotationY;
			rotationY -= eachAngle * 180 / Math.PI;

			TweenLite.killTweensOf(this, true);
			TweenLite.from(this, tweenTime, {rotationY: _rotationY, onComplete: onComplete});
			addEventListener(Event.ENTER_FRAME, onEnterFrame);

			var _index:int = index - maxPhotos;
			while(_index < 0)
				_index += objArr.length;
			var addnew:Boolean = true;
			if(objArr.length==2){
				addnew = Boolean(_index<=0);
			}
			addItem(_index, false,addnew);
		}

		private function onComplete(e:Event = null):void
		{//动作完成
			removeEventListener(Event.ENTER_FRAME, onEnterFrame);

			addEventListener(RIGHT, prev);
			addEventListener(LEFT, next);

			onEnterFrame(null);
		}

		private var maxPhotos:int = 1;//半圈图片数量
		private var headAngle:Number = 0;//list头部图片旋转角度
		private var railAngle:Number = 0;//list尾部图片旋转角度

		private function get eachAngle():Number
		{//图片间夹角大小
			return (Math.PI * 2 / (maxPhotos * 2 + 1));
		}

		private var list:Array;//保存显示的图片的双向列表

		/**
		 * url:	图片地址
		 * _head:	true将图片添加在list列表的头部，false添加到尾部
		 * 将图片添加到舞台，
		 */
		private function addItem(_index:int, _head:Boolean = true, addnew:Boolean=true):void
		{
			if(objArr ==null || objArr.length<=_index)
				return;
			var obj:Object = objArr[_index];
			var url:String = obj.icon;
			logs.adds(url);
			//var pw:int = stageWidth/10;
			var pw:int = stageHeight/4;
			var mc:PhotoLoader = new PhotoLoader(url,-pw*1.4);
			mc.addEventListener(MouseEvent.MOUSE_DOWN, selected);
			mc.addEventListener(MouseEvent.MOUSE_UP, selected);

			var picBg:Sprite = new Sprite();
			with(picBg.graphics)
			{
				beginFill(0x0,.1);
				drawRect(-pw,-pw,pw*2,pw*2);
				endFill();
			}
			mc.addChild(picBg);
			mc.visible = addnew;

			var s:String = String(obj.name);
			var txt:TextField = ViewSet.makeTxtLine(s,60,0xffffff);
			//txt.scaleY = txt.scaleX = 1/2.5;
			txt.x = -txt.textWidth/2;
			txt.y = pw*.9;
			mc.addChild(txt);

			mc.obj = {url:url,name:s,index:_index};

			addChild(mc);
			if (list == null)
			{//第一张图初始化列表，及角度
				list = new Array;
				headAngle = -Math.PI / 2;
				railAngle = headAngle + eachAngle;
			}

			if (list.length < maxPhotos * 2 + 1)
			{
				if (_head)
				{//添加到头部
					list.push(mc);
					mc.x = -r * Math.cos(headAngle);
					mc.z = r * Math.sin(headAngle);
					headAngle -= eachAngle;
				}
				else
				{//添加到尾部
					list.unshift(mc);
					mc.x = -r * Math.cos(railAngle);
					mc.z = r * Math.sin(railAngle);
					railAngle += eachAngle;
				}
			}
			else
			{
				var old:PhotoLoader;
				if (_head)
				{//添加到头部,删除尾部图片
					list.push(mc);
					old = list.shift();
				}
				else
				{//添加到尾部,删除头部图片
					list.unshift(mc);
					old = list.pop();
				}
				mc.x = old.x;
				mc.y = old.y;
				mc.z = old.z;
				removeChild(old);
			}
			sortItems();
		}

		public var curPicture:PhotoLoader;
		private function sortItems():void
		{//重新排列图片在舞台的深度及旋转角度
			var arr:Array = new Array;
			for (var i:int = 0; i < numChildren; i++)
			{
				var mc:PhotoLoader = getChildAt(i) as PhotoLoader;
				mc.rotationY = -rotationY;
				mc.scaleY = mc.scaleX = 1.0;
				if (parent)
					mc.rotationX = -parent.rotationX;
				var posA:Vector3D = mc.transform.matrix3D.position;
				posA = this.transform.matrix3D.deltaTransformVector(posA);
				var n:Number = 1 - (r - (posA.z)) / r/2;
				mc.alpha = 1.7 - n;
				if (posA.z > -r * .95){
					//mc.filters = [new BlurFilter(20*n, 20*n)];
				}else{
					mc.filters = [];
					curPicture = mc;
				}
				mc.scaleY = mc.scaleX = 1.0-(r+posA.z)/r/8;
				arr.push(mc);
			}
			if (arr.length < 2)
				return;
			arr.sort(depthSort);
			for (i = 0; i < arr.length; i++)
			{
				addChildAt(arr[i], i);
			}
		}

		private function depthSort(objA:DisplayObject, objB:DisplayObject):int
		{//深度（z）比较函数
			var posA:Vector3D = objA.transform.matrix3D.position;
			posA = this.transform.matrix3D.deltaTransformVector(posA);
			var posB:Vector3D = objB.transform.matrix3D.position;
			posB = this.transform.matrix3D.deltaTransformVector(posB);
			return posB.z - posA.z;
		}

		private var deltaAngle:int = 0;

		private function onEnterFrame(event:Event):void
		{//运动补间效果时，重新图片位置和旋转角度
			if (numChildren > 1)
				sortItems();
		}

		private function quit(e:Event = null):void
		{//退出时清除事件
			if (stage == null || !visible)
				return;
			removeEventListener(CLICK, quit);
			removeEventListener(RIGHT, prev);
			removeEventListener(LEFT, next);
			removeEventListener(Event.ENTER_FRAME, onEnterFrame);
		}
	}
}
